﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WeChatJumpGameHelper
{
    public partial class Form1 : Form
    {
        private static readonly string logPathPoint = "./log.txt";
        private static readonly string logPathColor = "./colorLog.txt";
        //起始点的范围
        private static readonly Point startPointMin = new Point(91, 334);
        private static readonly Point startPointMax = new Point(285, 380);
        private static readonly Point endPointMin = new Point(91, 269);
        private static readonly Point endPointMax = new Point(284, 314);
        private static readonly int searchArea = 30;
        private static readonly Point startPointSearchBase = new Point(50, 200);
        private static readonly Point endPointSearchBase = new Point(50, 200);
        private static readonly Color headColor = Color.FromArgb(53, 54, 66);//小人头部颜色

        public Form1()
        {
            InitializeComponent();
        }

        private void DoScreenShot()
        {
            FileFolderHelper.ClearFolder("./screencap");
            string fileName = "./screencap/" + DateTime.Now.Ticks.ToString() + ".png";
            AdbHelper.ScreenShot(fileName);
            if (File.Exists(fileName))
            {
                pictureBox1.BackgroundImage = new Bitmap(fileName);
            }
            else
            {
                Stop();
            }
            pictureBox1.Refresh();
        }

        private void GetStartPoint()
        {
            int startPointX = 0;
            int startPointY = 0;
            Bitmap map = (Bitmap)pictureBox1.BackgroundImage;
            for (int j = startPointSearchBase.Y; j < map.Height; j++)
            {
                for (int i = startPointSearchBase.X; i < map.Width; i++)
                {
                    Color curColor = map.GetPixel(i, j);
                    if (headColor.isSimilarColor(curColor))
                    {
                        int index = i;
                        for (; index < map.Width; index++)
                        {
                            curColor = map.GetPixel(index, j);
                            bool isSimilar = headColor.isSimilarColor(curColor);
                            if (!isSimilar) break;
                        }
                        int length = index - i;
                        if (!(length >= 4 && length <= 10))
                        {
                            continue;
                        }
                        startPointX = (index + i) / 2;
                        startPointY = j + 62;
                        if (!headColor.isSimilarColor(map.GetPixel(startPointX, j + 23)))
                        {
                            continue;
                        }
                        txtStartPointX.Text = startPointX.ToString();
                        txtStartPointY.Text = startPointY.ToString();
                        return;
                    }
                }
            }
        }

        private void GetEndPoint()
        {
            bool isRect = true;//默认方形
            Bitmap map = (Bitmap)pictureBox1.BackgroundImage;
            int endPointX = 0;
            int endPointY = 0;
            int j;
            int sx = int.Parse(txtStartPointX.Text);
            bool startPointIsLeft = sx < map.Width / 2;//小人在左边
            for (j = endPointSearchBase.Y; j < map.Height; j++)
            {
                int i = startPointIsLeft ? map.Width / 2 : endPointSearchBase.X;
                int endCheckIndex = startPointIsLeft ? map.Width : map.Width / 2;
                for (; i < endCheckIndex; i++)
                {
                    Color upColor = map.GetPixel(i, j - 1);
                    Color curColor = map.GetPixel(i, j);
                    bool isSimilar = upColor.isSimilarColor(curColor);
                    if (!isSimilar)
                    {
                        int index = i;
                        for (; index < map.Width; index++)
                        {
                            upColor = map.GetPixel(index, j - 1);
                            curColor = map.GetPixel(index, j);
                            isSimilar = upColor.isSimilarColor(curColor);
                            if (isSimilar) break;
                        }
                        if (index - i >= 5) isRect = false;//上方较平整，为圆形
                        endPointX = (index + i) / 2;
                        //MessageBox.Show("endPointX:" + endPointX);
                        goto tag;
                    }
                }
            }
            tag:
            int maxX = 0;//每一行的边缘
            int maxX_decreaseTime = 0;//边缘X坐标减少次数，减小2次算 找到
            int minX = map.Width - 1;//每一行的边缘
            int minX_increaseTime = 0;//边缘X坐标增加次数，减小2次算 找到
            bool checkLeftToRight = endPointX < map.Width / 2 ? true : false;//小人在右边，就从左往右检查
            if (checkLeftToRight)
            {
                for (int height = j; height < map.Height; height++)
                {
                    for (int width = 10; width <= endPointX; width++)
                    {
                        Color rightColor = map.GetPixel(width + 1, height);
                        Color curColor = map.GetPixel(width, height);
                        bool isSimilar = rightColor.isSimilarColor(curColor);
                        if (!isSimilar)
                        {
                            if (width < minX)
                            {
                                minX = width;
                            }
                            else
                            {
                                minX_increaseTime++;
                                if (minX_increaseTime == 4)
                                {
                                    if (!isRect)//圆形
                                    {
                                        endPointY = height;
                                    }
                                    else//方形
                                    {
                                        endPointY = height - 4;
                                    }
                                    //MessageBox.Show("endPointY=" + endPointY);
                                    goto tag2;
                                }
                            }
                            break;
                        }
                    }
                }
            }
            else
            {
                for (int height = j; height < map.Height; height++)
                {
                    for (int width = map.Width - 1; width >= endPointX; width--)
                    {
                        Color leftColor = map.GetPixel(width - 1, height);
                        Color curColor = map.GetPixel(width, height);
                        bool isSimilar = leftColor.isSimilarColor(curColor);
                        if (!isSimilar)
                        {
                            if (width > maxX)
                            {
                                maxX = width;
                            }
                            else
                            {
                                maxX_decreaseTime++;
                                if (maxX_decreaseTime == 4)
                                {
                                    if (!isRect)//圆形
                                    {
                                        endPointY = height;
                                    }
                                    else//方形
                                    {
                                        endPointY = height - 4;
                                    }
                                    //MessageBox.Show("endPointY=" + endPointY);
                                    goto tag2;
                                }
                            }
                            break;
                        }
                    }
                }
            }
            tag2:
            txtEndPointX.Text = endPointX.ToString();
            txtEndPointY.Text = endPointY.ToString();
            return;
        }

        private void Start()
        {
            this.timer1.Enabled = true;
            this.btnStart.Text = "暂停";
        }
        private void Stop()
        {
            this.timer1.Enabled = false;
            this.btnStart.Text = "开始";
        }

        private void doJump()
        {
            double dist = Math.Sqrt(
                            Math.Pow(int.Parse(txtStartPointX.Text) - int.Parse(txtEndPointX.Text), 2) +
                            Math.Pow(int.Parse(txtStartPointY.Text) - int.Parse(txtEndPointY.Text), 2));
            int delaymillis = (int)dist * int.Parse(txtStrength.Text) / 1150;
            int x = 260 + new Random().Next(20);
            int y = 530 + new Random().Next(20);
            //CmdHelper.Execute(@"adb shell input swipe 280 550 280 550 " + millis);
            CmdHelper.Execute(String.Format("adb shell input swipe {0} {1} {2} {3} {4}", x, y, x, y, delaymillis));
            //this.timer1.Interval = new Random().Next(200 + delaymillis, 500 + delaymillis);
            this.timer1.Interval = 1500 + (int)(2 * delaymillis);
            WritePointLog(txtStartPointX.Text + "        ," + txtStartPointY.Text + "    " + txtEndPointX.Text + "     ," + txtEndPointY.Text);
        }

        private void WritePointLog(string str)
        {
            LogHelper.WriteLog(logPathPoint, str);
        }
        private void WriteColorLog(string str)
        {
            LogHelper.WriteLog(logPathColor, "-------------------------------------");
            LogHelper.WriteLog(logPathColor, str);
        }

        private void DrawStartEndPoint()
        {
            int ax = int.Parse(txtStartPointX.Text);
            int ay = int.Parse(txtStartPointY.Text);
            int bx = int.Parse(txtEndPointX.Text);
            int by = int.Parse(txtEndPointY.Text);

            Bitmap bmp = (Bitmap)pictureBox1.BackgroundImage;
            int length = 5;
            for (int i = ax - length; i <= ax + length; i++)
            {
                try
                {
                    bmp.SetPixel(i, ay, Color.White);
                    bmp.SetPixel(i, ay - 1, Color.White);
                    bmp.SetPixel(i, ay + 1, Color.White);
                }
                catch (Exception e) { }
            }
            for (int i = ay - length; i <= ay + length; i++)
            {
                try
                {
                    bmp.SetPixel(ax, i, Color.White);
                    bmp.SetPixel(ax - 1, i, Color.White);
                    bmp.SetPixel(ax + 1, i, Color.White);
                }
                catch (Exception e) { }
            }
            for (int i = bx - length; i <= bx + length; i++)
            {
                try
                {
                    bmp.SetPixel(i, by, Color.Purple);
                    bmp.SetPixel(i, by - 1, Color.Purple);
                    bmp.SetPixel(i, by + 1, Color.Purple);
                }
                catch (Exception e) { }
            }
            for (int i = by - length; i <= by + length; i++)
            {
                try
                {
                    bmp.SetPixel(bx, i, Color.Purple);
                    bmp.SetPixel(bx - 1, i, Color.Purple);
                    bmp.SetPixel(bx + 1, i, Color.Purple);
                }
                catch (Exception e) { }
            }
            pictureBox1.BackgroundImage.Save("./screencap2/" + DateTime.Now.Ticks.ToString() + ".png");
            pictureBox1.Refresh();
        }

        #region UI事件
        private void Form1_Load(object sender, EventArgs e)
        {
            DoScreenShot();
        }
        private void pictureBox1_BackgroundImageChanged(object sender, EventArgs e)
        {
            txtStartPointX.Text = txtStartPointY.Text = txtEndPointX.Text = txtEndPointY.Text = "0";
            GetStartPoint();
            GetEndPoint();
            DrawStartEndPoint();
        }
        //单击 起点
        private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                txtStartPointX.Text = e.Location.X.ToString();
                txtStartPointY.Text = e.Location.Y.ToString();
            }
            else
            {
                txtEndPointX.Text = e.Location.X.ToString();
                txtEndPointY.Text = e.Location.Y.ToString();
            }
            DrawStartEndPoint();
        }
        private void btn_ScreenShot_Click(object sender, EventArgs e)
        {
            DoScreenShot();
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            labelLocation.Text = e.Location.X + "," + e.Location.Y;
            Bitmap bmp = (Bitmap)pictureBox1.BackgroundImage;
            if (bmp == null) return;
            labelARGB.Text = bmp.GetPixel(e.Location.X, e.Location.Y).ToArgb().ToString();
        }
        private void btn_logColor_Click(object sender, EventArgs e)
        {
            Bitmap bmp = (Bitmap)pictureBox1.BackgroundImage;
            int ax = int.Parse(txtStartPointX.Text);
            int ay = int.Parse(txtStartPointY.Text);
            int bx = int.Parse(txtEndPointX.Text);
            int by = int.Parse(txtEndPointY.Text);
            string logPic = "";
            for (int j = ay - 30; j <= ay + 30; j++)
            {
                string log = "";
                for (int i = ax - 30; i <= ax + 30; i++)
                {
                    //log += String.Format("{0,12}", bmp.GetPixel(i, j).ToArgb().ToString());
                    Color c = bmp.GetPixel(i, j);
                    log += String.Format("{0,3},{1,3},{2,3} ", c.R, c.G, c.B);
                }
                logPic += "\r\n" + log;
            }
            WriteColorLog(logPic);
            logPic = "";
            for (int j = by - 30; j <= by + 30; j++)
            {
                string log = "";
                for (int i = bx - 30; i <= bx + 30; i++)
                {
                    //log += String.Format("{0,12}", bmp.GetPixel(i, j).ToArgb().ToString());
                    Color c = bmp.GetPixel(i, j);
                    log += String.Format("{0,3},{1,3},{2,3} ", c.R, c.G, c.B);
                }
                logPic += "\r\n" + log;
            }
            WriteColorLog(logPic);
        }
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (this.timer1.Enabled)
            {
                Stop();
            }
            else
            {
                Start();
            }
        }

        private void btnJump_Click(object sender, EventArgs e)
        {
            doJump();
            Thread.Sleep(2000);
            DoScreenShot();
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            DoScreenShot();       
            int width = pictureBox1.BackgroundImage.Width;
            int sx = int.Parse(txtStartPointX.Text);
            int sy = int.Parse(txtStartPointY.Text);
            int ex = int.Parse(txtEndPointX.Text);
            int ey = int.Parse(txtEndPointY.Text);
            if (sx > startPointMin.X - searchArea //起点范围合法
                && sx < startPointMax.X + searchArea
                && sy > startPointMin.Y - searchArea
                && sy < startPointMax.Y + searchArea
                && ex > endPointMin.X - searchArea //终点范围合法
                && ex < endPointMax.X + searchArea
                && ey > endPointMin.Y - searchArea
                && ey < endPointMax.Y + searchArea
                && Math.Abs(sx - ex) > 20//起点终点距离不是 太近
                && Math.Abs(sy - ey) > 20
                && ((sx < width / 2 && ex >= width / 2) || sx >= width / 2 && ex < width / 2)//起终点不在同一侧
                && ey < sy)//终点比起点高
            {
                doJump();
            }
            else
            {
                //doJump();
                Stop();
                MessageBox.Show("起止点数据异常，需手动确认");
            }
        }

        #endregion

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Show();
                this.WindowState = FormWindowState.Normal;
                this.Activate();
            }
            else
            {
                this.WindowState = FormWindowState.Minimized;
                this.Hide();
            }
        }

        private void toolStripMenuItemExit_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("你确定要退出程序吗？", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                notifyIcon1.Visible = false;
                this.Close();
                this.Dispose();
                Application.Exit();
            }
        }

        private void toolStripMenuItemHide_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

        private void toolStripMenuItemShow_Click(object sender, EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
            this.Activate();
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide(); //或者是this.Visible = false;
                this.notifyIcon1.Visible = true;
            }
        }
    }
}
